// 8085View.cpp : implementation of the CMy8085View class
//

#include "stdafx.h"
#include "8085.h"

#include "8085Doc.h"
#include "8085View.h"
#include "Parse.h"
#include "MyException.h"
#include "8085Display.h"
#include "MainFrm.h"
#include "GreenTriangle.h"
#include "BkPtListDialog.h"
#include "GlobalFunctions.h"
#include "HelpDialog.h"
#include "EditPreferences.h"
#include <stdio.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMy8085View
IMPLEMENT_DYNCREATE(CMy8085View, CCrystalEditView)

BEGIN_MESSAGE_MAP(CMy8085View, CCrystalEditView)
	//{{AFX_MSG_MAP(CMy8085View)
	ON_COMMAND(ID_BUTTON_COMPILE, OnButtonCompile)
	ON_UPDATE_COMMAND_UI(ID_BUTTON_COMPILE, OnUpdateButtonCompile)
	ON_WM_CREATE()
	ON_COMMAND(ID_COMPILE_PROGRAM, OnCompileProgram)
	ON_UPDATE_COMMAND_UI(ID_COMPILE_PROGRAM, OnUpdateCompileProgram)
	ON_COMMAND(ID_BUTTON_SHOW_ADDRESS, OnButtonShowAddress)
	ON_UPDATE_COMMAND_UI(ID_BUTTON_SHOW_ADDRESS, OnUpdateButtonShowAddress)
	ON_COMMAND(ID_ACCEL_RUN, OnAccelRun)
	ON_UPDATE_COMMAND_UI(ID_ACCEL_RUN, OnUpdateAccelRun)
	ON_COMMAND(ID_ACCEL_STEPINTO, OnAccelStepInto)
	ON_COMMAND(ID_ACCEL_RUNTO_CURSOR, OnAccelRuntoCursor)
	ON_COMMAND(ID_ACCEL_STEPOVER, OnAccelStepover)
	ON_COMMAND(ID_DEBUG_COMPILE, OnDebugCompile)
	ON_UPDATE_COMMAND_UI(ID_DEBUG_COMPILE, OnUpdateDebugCompile)
	ON_COMMAND(ID_DEBUG_STEP_INTO, OnDebugStepInto)
	ON_UPDATE_COMMAND_UI(ID_DEBUG_STEP_INTO, OnUpdateDebugStepInto)
	ON_COMMAND(ID_DEBUG_STEP_OVER, OnDebugStepOver)
	ON_UPDATE_COMMAND_UI(ID_DEBUG_STEP_OVER, OnUpdateDebugStepOver)
	ON_COMMAND(ID_DEBUG_RUN, OnDebugRun)
	ON_UPDATE_COMMAND_UI(ID_DEBUG_RUN, OnUpdateDebugRun)
	ON_COMMAND(ID_DEBUG_BREAKPOINTS_LIST, OnDebugBreakpointsList)
	ON_COMMAND(ID_TOGGLE_BKPT, OnToggleBkpt)
	ON_COMMAND(ID_HELP_HTMLDOCUMENTATION, OnHelpHtmlDocumentation)
	ON_COMMAND(ID_ACCEL_HELP, OnAccelHelp)
	ON_COMMAND(ID_BUTTON_HELP, OnButtonHelp)
	ON_COMMAND(ID_ENABLE_DISABLE_BKPT, OnEnableDisableBkpt)
	ON_WM_CHAR()
	ON_COMMAND(ID_ACCEL_CLOSE_SIMULATION, OnAccelCloseSimulation)
	ON_WM_CONTEXTMENU()
	ON_COMMAND(ID_MYPOPUP_MENU_UNDO, OnMypopupMenuUndo)
	ON_COMMAND(ID_MYPOPUP_MENU_SELECT_ALL, OnMypopupMenuSelectAll)
	ON_COMMAND(ID_MYPOPUP_MENU_CUT, OnMypopupMenuCut)
	ON_COMMAND(ID_MYPOPUP_MENU_COPY, OnMypopupMenuCopy)
	ON_COMMAND(ID_MYPOPUP_MENU_PASTE, OnMypopupMenuPaste)
	ON_COMMAND(ID_MYPOPUP_MENU_DELETE, OnMypopupMenuDelete)
	ON_COMMAND(ID_EDIT_PREFERENCES, OnEditPreferences)
	ON_COMMAND(ID_BUTTON_EDIT_PREFERENCES, OnButtonEditPreferences)
	ON_COMMAND(ID_DISPLAY_BREAKPOINT_LIST, OnDisplayBreakpointList)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CCrystalEditView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CCrystalEditView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CCrystalEditView::OnFilePrintPreview)
END_MESSAGE_MAP()


CMy8085Doc*			CMy8085View::m_pCurrentDoc	=NULL;
CMy8085View*		CMy8085View::m_pCurrentView	=NULL;
CMDIChildWnd*		CMy8085View::m_pChildFrame	=NULL;
/////////////////////////////////////////////////////////////////////////////
// CMy8085View construction/destruction

CMy8085View::CMy8085View()
{
	// TODO: add construction code here
    m_p8085Display		= NULL; // the 8085 display
    m_nMargin			= 20;
    m_bLEDButtonState	= FALSE;
    m_cSrcArrow.SetFillColour(RGB(0,236,236));
	m_cSrcArrow.SetBorderColour( COLORINDEX_SELMARGIN ); 
	m_8085_display_window_position = 0;
	m_bShortHelpOnStatusBar  = TRUE;
}

CMy8085View::~CMy8085View()
{
	delete m_8085_display_window_position;
}

BOOL CMy8085View::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	BOOL bPreCreated = CCrystalEditView::PreCreateWindow(cs);
	//cs.style &= ~(ES_AUTOHSCROLL|WS_HSCROLL);	// Enable word-wrapping
	return bPreCreated;
}

/////////////////////////////////////////////////////////////////////////////
// CMy8085View printing

BOOL CMy8085View::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default CCrystalEditView preparation
	return CCrystalEditView::OnPreparePrinting(pInfo);
}

void CMy8085View::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
	// Default CCrystalEditView begin printing.
	CCrystalEditView::OnBeginPrinting(pDC, pInfo);
}


void CMy8085View::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
{
	// Default CCrystalEditView end printing
	CCrystalEditView::OnEndPrinting(pDC, pInfo);
}

/////////////////////////////////////////////////////////////////////////////
// CMy8085View diagnostics

#ifdef _DEBUG
void CMy8085View::AssertValid() const
{
	//CCrystalEditView::AssertValid();
}

void CMy8085View::Dump(CDumpContext& dc) const
{
	CCrystalEditView::Dump(dc);
}

CMy8085Doc* CMy8085View::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMy8085Doc)));
	return (CMy8085Doc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMy8085View message handlers

void CMy8085View::OnButtonCompile() 
{
	// TODO: Add your command handler code here
    CMy8085Doc *pDoc = GetDocument();
    C8085Object *p8085Object = pDoc->Get8085Object();

    if(pDoc->IsDisplayOpen()) 
        return;

    if(pDoc->IsModified())
        pDoc->SaveModified();
    try
    {
        // erase the previous triangle which shows the source line 
        CWaitCursor cw;
        GetDebugObject().Close();
        m_cSrcArrow.Draw(GetDC(),TRUE);  
        p8085Object->ResetMachine();
        pDoc->ParseFile(pDoc->GetPathName());
        p8085Object->StartMachine();
        
        m_p8085Display = new C8085Display(this);
        m_p8085Display->CreateAll(C8085Display::IDD,GetParent());
        m_p8085Display->Refresh();
        m_p8085Display->Refresh();

		if ( m_8085_display_window_position )
			m_p8085Display->SetWindowPlacement( m_8085_display_window_position );

		m_p8085Display->ShowWindow(SW_SHOW);

        //GetDocument()->SetDisplayOpen();  // moved to C8085Display::InitDialog
        InitDebugInfo();
        ValidateBkPts();
    }
    catch(CMyException& e)
    {
        // to catch errors from parser 
        DisplayException(&e);
    }
}

void CMy8085View::OnUpdateButtonCompile(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
    if(GetDocument()->IsDisplayOpen()) pCmdUI->Enable(FALSE);
    else pCmdUI->Enable(TRUE);    	
}

void CMy8085View::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) 
{
	// TODO: Add your specialized code here and/or call the base class
    // save the current document pointer in the variable m_pCurrentDoc
    // so that it can be used by the various controls (like InstructionBox)
    // without much overhead.
    if(bActivate)
    {
        m_pCurrentDoc = GetDocument();  // see CMy8085View::GetCurrentDoc()
        m_pCurrentView = this;          // see CMy8085View::GetCurrentView()
        CMDIFrameWnd *pFrame = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
        // Get the active MDI child window.
        m_pChildFrame = (CMDIChildWnd *) pFrame->GetActiveFrame();
    }
	CCrystalEditView::OnActivateView(bActivate, pActivateView, pDeactiveView);
}

inline C8085Object * CMy8085View::Get8085Object()
{
    return GetDocument()->Get8085Object();
}

// display the exception message from the parser
void CMy8085View::DisplayException(CMyException *pException)
{
    CParse *pParser = GetDocument()->GetParserObject();
    // get the exception object;
    CMyException eo = pParser->GetExceptionObject();
    StatusBarMessage(eo.GetErrorMessage());

    int nRet = MessageBox(eo.GetErrorMessage()+
        "\n\nPress OK to goto source","8085 ISS",MB_OKCANCEL);
    // if ok then goto the position where error occured
    if(nRet==IDOK)
    {
		/*-vijay 
		CEdit& edit = GetEditCtrl();
        int nChar = edit.LineIndex(eo.GetLineNumber()-1)+eo.GetColumn()-1;
        edit.SetSel(nChar,nChar);
		*/
        
		CPoint pt( eo.GetColumn()-1 , eo.GetLineNumber()-1);
		SetCursorPos(pt);
		SetSelection(pt, pt);
		SetAnchor(pt);
		EnsureVisible(pt);
    }
}

int CMy8085View::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CCrystalEditView::OnCreate(lpCreateStruct) == -1)
		return -1;
	// TODO: Add your specialized creation code here
    //-vijay GetEditCtrl().SetMargins(m_nMargin,-1);
	return 0;
}


// This is called when 'F7' is pressed
void CMy8085View::OnCompileProgram() 
{
	// TODO: Add your command handler code here
    OnButtonCompile();
}

void CMy8085View::OnUpdateCompileProgram(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
    pCmdUI->Enable(!GetDocument()->IsDisplayOpen());
}

void CMy8085View::ShowSourcePosition(word addr)
{
#if 0
    TEXTMETRIC m;
    GetDC()->GetTextMetrics(&m);
    int nCharHeight = m.tmHeight;

    m_cSrcArrow.Draw(GetDC(),TRUE);  // erase the previous one 
    m_cSrcArrow.SetProperty(0,nCharHeight*(nSrcLine)+nCharHeight/2+1,10);

    m_cSrcArrow.Draw(GetDC());  // draw the new one
    /*-vijay
	CEdit &edit = ((CCrystalEditView*)m_p8085Display->GetView())->GetEditCtrl();
    int nChar = edit.LineIndex(nSrcLine);
    edit.SetSel(nChar,nChar);   // the cursor will now be at the desired line
    m_cSrcArrow.SetProperty(0,nCharHeight*(nSrcLine - edit.GetFirstVisibleLine())
        +nCharHeight/2+1,10);
    m_cSrcArrow.Draw(GetDC());  // draw the new one
	*/
#endif
	PostMessage( WM_ACTIVATE );
    int nSrcLine = GetDebugObject().GetSourceLine(addr)-1;
	CPoint pt( 0 , nSrcLine );

	SetCursorPos(pt);
	SetSelection(pt, pt);
	SetAnchor(pt);
	EnsureVisible(pt);

	DWORD dwFlags = GetLineFlags(pt.y);
	DWORD dwMask = LF_EXECUTION;
	m_pTextBuffer->SetLineFlag(pt.y, dwMask, (dwFlags & dwMask) == 0);
}

void CMy8085View::ShowCurrentPosition(void)
{
    ShowSourcePosition(Get8085Object()->GetIP());
}

void CMy8085View::InitDebugInfo()
{
    try
    {
        GetDebugObject().Open(
            GetDocument()->GetParserObject()->GetDebugFileName(),"rt");
        GetDebugObject().Read();  // read the debug info
    }
    catch(CMyException &cm)
    {
        cm.ShowErrorMessage();
    }
}


// display a message in the status bar
void CMy8085View::StatusBarMessage(const CString& str)
{
    CMainFrame *pFrame=(CMainFrame *)AfxGetApp()->m_pMainWnd;
    pFrame->ShowErrorMessageInStatusBar(str);
}


void CMy8085View::OnButtonShowAddress() 
{
	// TODO: Add your command handler code here
    try
    {
        word addr = AddressAtCursor();
        m_p8085Display->ShowDisAssemblyPosition(addr);
    }
    catch(CMyException &cm)
    {
        cm.ShowErrorMessage();
    }
}

void CMy8085View::OnUpdateButtonShowAddress(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
    pCmdUI->Enable(GetDocument()->IsDisplayOpen());
}

// compile and run
void CMy8085View::OnAccelRun() 
{
	// TODO: Add your command handler code here
    // if compilation is successful run the program
    if(Compile())
        m_p8085Display->Run();
}

void CMy8085View::OnUpdateAccelRun(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
    if(GetDocument()->IsDisplayOpen()) 
        pCmdUI->Enable(!m_p8085Display->IsAnimating());
     else
         pCmdUI->Enable();
}
 
void CMy8085View::OnAccelStepInto() 
{
    // TODO: Add your command handler code here
    if(Compile())
        m_p8085Display->StepInto();
}

// return TRUE if compilation is successful
// Used by the Accelerator keys to compile the program
int CMy8085View::Compile()
{
    // first try to compile
    if(!GetDocument()->IsDisplayOpen()) 
    {
        OnButtonCompile();
        if(GetDocument()->IsDisplayOpen()) 
        {
            Sleep(100); // give some time for the display to come up
            return TRUE;
        }
    }
    else if(!m_p8085Display->IsAnimating())
        return TRUE;
    return FALSE;
}

void CMy8085View::OnAccelRuntoCursor() 
{
	// TODO: Add your command handler code here
    if(Compile())
    {
        try
        {
            word addr = AddressAtCursor();
            m_p8085Display->RunToCursor(addr);
        }
        catch(CMyException &cm)
        {
            cm.ShowErrorMessage();
        }
    }
}

// return the 8085 memory address corresponding to a line in the source file
word CMy8085View::AddressAtCursor()
{
    // unsigned int nLine= GetEditCtrl().LineFromChar(-1);
	unsigned int nLine= GetCursorPos().y;
	return AddressAtPoint( nLine );
    // throws an exception if not found
    //return GetDebugObject().GetMemoryAddress(nLine+1); 
}

// return the 8085 memory address corresponding to a line in the source file
word CMy8085View::AddressAtPoint( unsigned int nLine)
{
    // throws an exception if not found
    return GetDebugObject().GetMemoryAddress(nLine+1); 
}

void CMy8085View::OnAccelStepover() 
{
	// TODO: Add your command handler code here
    if(Compile())
    {
        m_p8085Display->StepOver();
    }
}

void CMy8085View::OnDebugCompile() 
{
	// TODO: Add your command handler code here
    Compile();	
}

void CMy8085View::OnUpdateDebugCompile(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
    if(!GetDocument())
        pCmdUI->Enable(FALSE);
    else
    {
        pCmdUI->Enable(!GetDocument()->IsDisplayOpen());    	
    }
}

void CMy8085View::OnDebugStepInto() 
{
	// TODO: Add your command handler code here
    OnAccelStepInto();
}

void CMy8085View::OnUpdateDebugStepInto(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
    if(!GetDocument())
        pCmdUI->Enable(FALSE);
    else
    {
        pCmdUI->Enable(!GetDocument()->IsAnimating());
    }
}

void CMy8085View::OnDebugStepOver() 
{
	// TODO: Add your command handler code here
    OnAccelStepover();	
}

void CMy8085View::OnUpdateDebugStepOver(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
    if(!GetDocument())
        pCmdUI->Enable(FALSE);
    else
    {
        pCmdUI->Enable(!GetDocument()->IsAnimating());
    }
}

void CMy8085View::OnDebugRun() 
{
	// TODO: Add your command handler code here
    OnAccelRun();	
}

void CMy8085View::OnUpdateDebugRun(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
    if(!GetDocument())
        pCmdUI->Enable(FALSE);
    else
    {
        if(GetDocument()->IsDisplayOpen()) 
            pCmdUI->Enable(!m_p8085Display->IsAnimating());
         else
             pCmdUI->Enable();
    }
}

void CMy8085View::OnDebugBreakpointsList() 
{
	DisplayBreakpointList( );
}
	
void CMy8085View::OnToggleBkpt() 
{
	int y = GetCursorPos( ).y;
	// TODO: Add your command handler code here
    if( GetDocument()->IsDisplayOpen()) {
		word addr;
		try
		{
			addr = AddressAtCursor();
			GetDocument( )->ToggleBkPt(addr);
			m_p8085Display->Refresh( );
			ToggleBkPtAtSource( y );
		}
		catch(CMyException& )
		{
			StandardBeep( );
		}
	} else {
		ToggleBkPtAtSource( y );
	}


#if 0
    if(!GetDocument()->IsDisplayOpen())
    {
		StandardBeep( );
        return;
    }
    word addr;
    try
    {
        addr = AddressAtCursor();
		ToggleBkPtAtAddress( addr );
    }
    catch(CMyException& )
    {
		CPoint pt	=	GetCursorPos();
		m_pTextBuffer->SetLineFlag( pt.y, LF_BREAKPOINT_DISABLED, FALSE, FALSE );
		StandardBeep( ); //MessageBeep( 0xFFFFFFFF );
    }
#endif
}

void CMy8085View::ToggleBkPtAtAddress( word addr )
{
	GetDocument()->ToggleBkPt(addr);
	try {
		int nSrcLine = GetDebugObject().GetSourceLine(addr)-1;
		ToggleBkPtAtSource( nSrcLine );
	}	// try

	catch( CMyException&  )
	{
		// probably there was no line number equivalent in the source code.

	}

	if( GetDocument()->IsDisplayOpen() )
		m_p8085Display->Refresh();
}

void CMy8085View::RemoveBkPtAtSource( int nSrcLine )
{
	CPoint pt( 0 , nSrcLine );

	SetCursorPos(pt);
	SetSelection(pt, pt);
	SetAnchor(pt);
	EnsureVisible(pt);

	DWORD dwFlags	= GetLineFlags(pt.y);
	DWORD dwMask	= LF_BREAKPOINT;

	if ( dwFlags & LF_BREAKPOINT )
		m_pTextBuffer->SetLineFlag( pt.y, LF_BREAKPOINT, FALSE, FALSE );

	if ( dwFlags & LF_BREAKPOINT_DISABLED )
		m_pTextBuffer->SetLineFlag( pt.y, LF_BREAKPOINT_DISABLED, FALSE, FALSE );
}

void CMy8085View::ToggleBkPtAtSource( int nSrcLine )
{
	CPoint pt( 0 , nSrcLine );

	SetCursorPos(pt);
	SetSelection(pt, pt);
	SetAnchor(pt);
	EnsureVisible(pt);

	DWORD dwFlags	= GetLineFlags(pt.y);
	DWORD dwMask	= LF_BREAKPOINT;

	if ( dwFlags & LF_BREAKPOINT )
		m_pTextBuffer->SetLineFlag( pt.y, LF_BREAKPOINT, FALSE, FALSE );
	else
		m_pTextBuffer->SetLineFlag( pt.y, LF_BREAKPOINT, TRUE, FALSE );

	if ( dwFlags & LF_BREAKPOINT_DISABLED ) {
		m_pTextBuffer->SetLineFlag( pt.y, LF_BREAKPOINT_DISABLED, FALSE, FALSE );
		m_pTextBuffer->SetLineFlag( pt.y, LF_BREAKPOINT, TRUE, FALSE );
	}
}

// makes sure that a breakpoint actually corresponds to a valid instruction
// This can happen since list of breakpoint is preserved across compiles
// and a valid breakpoint in one run may not be valid in the next because of 
// edits to the assembly code.
void CMy8085View::ValidateBkPts()
{
    int nCount=0;

	GetDocument( )->DeleteAllBkPt( );
	for ( int i=0 ; i < m_pTextBuffer->GetLineCount( ); i++ )
	{
		DWORD dwMask	= m_pTextBuffer->GetLineFlags( i );
        try
        {
			DWORD mask = LF_BREAKPOINT | LF_BREAKPOINT_DISABLED;
			if ( dwMask & mask ) {
				word addr	=	GetDebugObject( ).GetMemoryAddress( i + 1 );

				if ( dwMask & LF_BREAKPOINT_DISABLED )
					GetDocument( )->AddBkPt( addr, i, FALSE );
				else
					GetDocument( )->AddBkPt( addr, i );
			}
		}
		catch( CMyException& )
		{
			RemoveBkPtAtSource( i );
			++nCount;
		}
	}
/*
    for(pt=GetDocument()->FirstBreakPoint() ; pt; pt=GetDocument()->NextBreakPoint())
    {
        try
        {
            // try to find out if this address actually corresponds to a valid
            // source line number
            int nSrcLine; 
            nSrcLine = GetDebugObject().GetSourceLine(pt->address)-1;
        }
        catch(CMyException& )
        {
            GetDocument()->DeleteBkPt(pt->address);
            ++nCount;
        }
    }
*/
    if(nCount)
    {
        ::ShowErrorMessage("One or more invalid breakpoints have been removed");        
    }

}

inline CDebugData& CMy8085View::GetDebugObject()
{
    return GetDocument()->m_cDebugInfo;
}

void CMy8085View::OnHelpHtmlDocumentation() 
{
	// TODO: Add your command handler code here
    //MessageBox("Not yet Implemented");
    //return;
    CMy8085App::Help();
}

void CMy8085View::OnAccelHelp() 
{
	// TODO: Add your command handler code here
	CMy8085App::Help();
}

void CMy8085View::OnButtonHelp() 
{
	// TODO: Add your command handler code here
	CMy8085App::Help();
}


void CMy8085View::OnEnableDisableBkpt() 
{
	// TODO: Add your command handler code here
    if(!GetDocument()->IsDisplayOpen())
    {
        StandardBeep( );
        return;
    }

    word addr;
    try
    {
        addr = AddressAtCursor();
		EnableDisableBkPt( addr );
		//EnableDisableBkPtAtSource( GetCursorPos( ).y );
    }
    catch(CMyException& )
    {
        StandardBeep( );
		return;
    }
}

void CMy8085View::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	CPoint	pt		= GetCursorPos();

	CCrystalEditView::OnChar(nChar, nRepCnt, nFlags);
	if (nChar == VK_RETURN) {
		DWORD	dwMask	= GetLineFlags( pt.y );;
		LPCTSTR	text	= m_pTextBuffer->GetLineChars( pt.y );
		int		pos		= skip_space( text );
	
		if ( ( pt.x <= pos ) && ( dwMask	& LF_BREAKPOINT ) ) {
			m_pTextBuffer->SetLineFlag( pt.y, dwMask, FALSE, FALSE );
			m_pTextBuffer->SetLineFlag( GetCursorPos( ).y, dwMask, TRUE, FALSE );
		}

	} // if
}

// save the position of the display window dialog and restore it next time
void CMy8085View::Set8085DisplayDialogWindowPosition()
{
	if ( ! m_8085_display_window_position )
		m_8085_display_window_position = new WINDOWPLACEMENT;
	m_p8085Display->GetWindowPlacement( m_8085_display_window_position );
}

void CMy8085View::OnAccelCloseSimulation() 
{
	if ( m_p8085Display )
		m_p8085Display->QuitSimulator( );
}

/////////////////////////////////////////////////////////////////////////////
// CSampleView message handlers

CCrystalTextBuffer *CMy8085View::LocateTextBuffer()
{
	return &GetDocument()->m_xTextBuffer;
}

void CMy8085View::OnInitialUpdate() 
{
	CCrystalEditView::OnInitialUpdate();

	SetFont(GetDocument()->m_lf);
}

void CMy8085View::OnUpdateIndicatorPosition(CCmdUI* pCmdUI)
{
	CCrystalEditView::OnUpdateIndicatorPosition( pCmdUI );

	if ( m_bShortHelpOnStatusBar ) {
		const char * str = GetAsmHelpText( GetCursorPos().y );
		if ( str )
			StatusBarMessage( str );
	}
}


void CMy8085View::OnContextMenu(CWnd* pWnd, CPoint point) 
{
	CMenu menu;
	menu.LoadMenu(IDR_POPUP_MENU);
    CMenu* pPopup = menu.GetSubMenu( 0 );

    pPopup->EnableMenuItem(ID_MYPOPUP_MENU_UNDO, !CanUndo( ) );
    pPopup->EnableMenuItem(ID_MYPOPUP_MENU_CUT, ! CanCut( ) );
    pPopup->EnableMenuItem(ID_MYPOPUP_MENU_COPY, ! CanCopy( ) );
    pPopup->EnableMenuItem(ID_MYPOPUP_MENU_PASTE, ! CanPaste( ) );
    pPopup->EnableMenuItem(ID_MYPOPUP_MENU_DELETE, ! CanCopy( ) );

    pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
      point.x, point.y,this); // use main window for cmds
}

void CMy8085View::OnMypopupMenuUndo() 
{
	// TODO: Add your command handler code here
	CCrystalEditView::OnEditUndo( );	
}


void CMy8085View::OnMypopupMenuSelectAll() 
{
	// TODO: Add your command handler code here
	CCrystalEditView::OnEditSelectAll( );	
}

void CMy8085View::OnMypopupMenuCut() 
{
	// TODO: Add your command handler code here
	CCrystalEditView::OnEditCut( );	
}

void CMy8085View::OnMypopupMenuCopy() 
{
	// TODO: Add your command handler code here
	CCrystalEditView::OnEditCopy( );	
}

void CMy8085View::OnMypopupMenuPaste() 
{
	// TODO: Add your command handler code here
	CCrystalEditView::OnEditPaste( );	
}

void CMy8085View::OnMypopupMenuDelete() 
{
	// TODO: Add your command handler code here
	CCrystalEditView::OnEditDelete( );
}


void CMy8085View::OnEditPreferences() 
{
	//BOOL	CMy8085Doc::m_bSyntaxHighlighting	= TRUE;
	CEditPreferences d;
	d.m_bMiniHelp	= GetDocument( )->m_bMiniHelp;
	d.m_bSyntaxHighlighting	= GetDocument( )->m_bSyntaxHighlighting;
	d.DoModal( );
	GetDocument( )->m_bMiniHelp = d.m_bMiniHelp;
	if ( GetDocument( )->m_bSyntaxHighlighting != d.m_bSyntaxHighlighting ) {
		UpdateView( this, 0, 0 );
		GetDocument( )->m_bSyntaxHighlighting = d.m_bSyntaxHighlighting;
	}
}

void CMy8085View::OnButtonEditPreferences() 
{
	// TODO: Add your command handler code here
	OnEditPreferences( );	
}


void CMy8085View::DrawMargin(CDC *pdc, const CRect &rect, int nLineIndex)
{
	CCrystalTextView::DrawMargin( pdc, rect, nLineIndex );
}


void CMy8085View::EnableDisableBkPtAtSource( int nLine )
{
	DWORD dwFlags	= GetLineFlags( nLine );

	if ( dwFlags & LF_BREAKPOINT ) {
		m_pTextBuffer->SetLineFlag( nLine , LF_BREAKPOINT, FALSE, FALSE );
		m_pTextBuffer->SetLineFlag( nLine , LF_BREAKPOINT_DISABLED, TRUE, FALSE );
	}
	else {
		m_pTextBuffer->SetLineFlag( nLine , LF_BREAKPOINT_DISABLED, FALSE, FALSE );
		m_pTextBuffer->SetLineFlag( nLine , LF_BREAKPOINT, TRUE, FALSE );
	}
}

void CMy8085View::EnableDisableBkPt(word addr)
{
    if( ! GetDocument()->IsABkPt( addr ) )
		return;
	unsigned enabled = GetDocument()->IsBkPtEnabled(addr);
	GetDocument()->EnableBkPt(addr,! enabled );
	unsigned int nSrcLine;
	if ( GetDebugObject().GetSourceLine(addr, nSrcLine ) ) {
		nSrcLine--;
		CPoint pt( 0 , nSrcLine );

		SetCursorPos(pt);
		SetSelection(pt, pt);
		SetAnchor(pt);
		EnsureVisible(pt);

		EnableDisableBkPtAtSource( pt.y );
	} // if
	if( GetDocument()->IsDisplayOpen() )
			m_p8085Display->Refresh();
}

void CMy8085View::OnDisplayBreakpointList() 
{
	// TODO: Add your command handler code here
	DisplayBreakpointList( );
}

void CMy8085View::DisplayBreakpointList() 
{
    CBkPtListDialog d;


    if(d.DoModal()==IDOK) {
		if(GetDocument()->IsDisplayOpen())
            m_p8085Display->Refresh();
	}
}
